package com.lge.pitchingcoins.ui.server;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.lge.pitchingcoins.R;
import com.lge.pitchingcoins.util.PitchingCoinsLog;
import com.lge.pitchingcoins.util.Util;
import com.lge.pitchingcoins.util.databases.PitchingCoinsDatabaseHandler;
import com.lge.pitchingcoins.util.sessions.GameCmdManager;
import com.lge.pitchingcoins.util.sessions.GameCmdManager.GameCmdSendDTO;
import com.lge.pitchingcoins.util.sessions.GameCmdProcessor;
import com.lge.pitchingcoins.util.sessions.ServerSession;
import com.lge.pitchingcoins.util.sessions.ServiceHelper;

import java.util.ArrayList;

@Deprecated
public class GameConnectForServerActivity extends Activity implements OnClickListener {
    public static int CHANGE_IS_GAME_PLAYING = 1000;
    public static int CONNECTOR_LIST_NOTIFY_DATA_SET_CHANGED = 1001;
    public static int SCORE_LIST_NOTIFY_DATA_SET_CHANGED = 1002;

    private Activity mActivity = null;

    private ServiceHelper serviceHelper = null;
    private ServerSession serverSession = null;

    private LinearLayout gameStartLayout = null;
    private Dialog gameStartLayoutDialog = null;
    private AlertDialog gameOverLayoutAlertDialog = null;
    private AlertDialog.Builder gameOverLayoutBuilder = null;
    private ListView connectorListView = null;
    private Button gameStartButton = null;

    private TextView winnerTextView = null;
    private ListView scoreListView = null;

    private ConnectorListAdapter connectorListAdapter = null;
    private ScoreListAdapter scoreListAdapter = null;

    private ArrayList<ClientScore> clientScoreArrayList = null;

    private boolean isGamePlaying = false;

    private GameCmdProcessor mGameCmdProcessor = null;
    private GameCmdManager mGameCmdManager = null;

    private GameCmdSendDTO mGameData = null;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == CHANGE_IS_GAME_PLAYING) {
                Util.setHomeKeyLock(mActivity, isGamePlaying);
            } else if (msg.what == CONNECTOR_LIST_NOTIFY_DATA_SET_CHANGED) {
                if (serverSession.numberOfClients() > 0) {
                    gameStartButton.setEnabled(true);
                } else {
                    gameStartButton.setEnabled(false);
                }

                connectorListAdapter.notifyDataSetChanged();
            } else if (msg.what == SCORE_LIST_NOTIFY_DATA_SET_CHANGED) {
                scoreListAdapter.notifyDataSetChanged();
            }
        }
    };


    // Getters and Setters
    public boolean isGamePlaying() {
        return isGamePlaying;
    }

    public void setGamePlaying(boolean isGamePlaying) {
        this.isGamePlaying = isGamePlaying;

        mHandler.sendEmptyMessage(CHANGE_IS_GAME_PLAYING);
    }


    // Callback Methods
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_game_connect_for_server);

        initComponent();
    }

    @Override
    protected void onResume() {
        if (serviceHelper != null) {
            serviceHelper.registerService(Util.PC_PORT);
        }

        if (serverSession == null) {
            serverSession = new ServerSession(this);

            gameStartLayoutDialog.show();
        }

        super.onResume();
    }

    @Override
    protected void onPause() {
        if (serviceHelper != null) {
            serviceHelper.tearDown();
        }

        if (serverSession != null) {
            sendMessageTo("IL", ServerSession.toAllString);

            gameStartButton.setVisibility(View.GONE);

            serverSession.tearDown();
            serverSession = null;
        }

        super.onPause();
    }

    @Override
    protected void onDestroy() {

        super.onDestroy();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            if (isGamePlaying) {
                //                Toast.makeText(getApplicationContext(), getString(R.string.cannotExitWhenPlayingGame), Toast.LENGTH_SHORT).show();
                return isGamePlaying;
            }
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.gameStartButton:
            gameStartButtonPressed();
            break;
        }
    }

    public void onMessageReceived(String message, String fromNickName) {
        PitchingCoinsLog.d("Server: " + message + "\nFrom: " + fromNickName);
        mGameData = GameCmdManager.parse(message, mGameCmdManager);



        //        GameCmdManager.pumpUp(mGameCmdProcessor.getCmdList());
        //        sendMessageTo(message, ServerSession.toAllString);
    }

    public void onClientEnteredOrLeave() {
        mHandler.sendEmptyMessage(CONNECTOR_LIST_NOTIFY_DATA_SET_CHANGED);
    }

    public void onGameFinished() {
        setGamePlaying(false);
        sendMessageTo("GO", ServerSession.toAllString);

        mHandler.sendEmptyMessage(SCORE_LIST_NOTIFY_DATA_SET_CHANGED);

        // TODO Set text to winnerTextView for nickname on the first place
        //        winnerTextView.setText(clientScoreArrayList.get(0).toString());

        // Save data to database
        PitchingCoinsDatabaseHandler mDatabaseHandler = new PitchingCoinsDatabaseHandler(this);
        mDatabaseHandler.openDatabase();

        for (ClientScore client : clientScoreArrayList) {
            mDatabaseHandler.insertNewScore(client.getNickname(), client.getScore());
        }

        mDatabaseHandler.closeDatabase();
        gameOverLayoutAlertDialog.show();
    }


    // Member Methods
    public void initComponent() {
        mActivity = this;

        serviceHelper = new ServiceHelper(this);
        serviceHelper.initializeNsd();

        clientScoreArrayList = new ArrayList<ClientScore>();

        initGameStartLayoutDialog();
        initGameOverLayoutAlertDialog();

        gameStartLayout = (LinearLayout)gameStartLayoutDialog.findViewById(R.id.gameStartLayout);
        connectorListView = (ListView)gameStartLayoutDialog.findViewById(R.id.connectorListView);
        gameStartButton = (Button)gameStartLayoutDialog.findViewById(R.id.gameStartButton);

        connectorListAdapter = new ConnectorListAdapter(this);
        connectorListView.setAdapter(connectorListAdapter);
        gameStartButton.setOnClickListener(this);

        mGameCmdProcessor = GameCmdProcessor.getInstance();
        mGameCmdManager = GameCmdManager.getInstance();



        Button willBeRemovedButton = (Button)findViewById(R.id.willBeRemovedButton);
        willBeRemovedButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                onGameFinished();
            }
        });
    }

    public void initGameStartLayoutDialog() {
        gameStartLayoutDialog = new Dialog(this);
        gameStartLayoutDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        gameStartLayoutDialog.setContentView(R.layout.view_connector_list);
        gameStartLayoutDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        gameStartLayoutDialog.setOnCancelListener(new OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialogInterface) {
                mActivity.finish();
            }
        });
    }

    public void initGameOverLayoutAlertDialog() {
        LayoutInflater inflater = (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
        View gameOverLayout = inflater.inflate(R.layout.view_game_over_for_alert_dialog, (ViewGroup)findViewById(R.id.gameOverLayout));

        winnerTextView = (TextView)gameOverLayout.findViewById(R.id.winnerTextView);

        scoreListAdapter = new ScoreListAdapter(this);
        scoreListView = (ListView)gameOverLayout.findViewById(R.id.scoreListView);
        scoreListView.setAdapter(scoreListAdapter);

        gameOverLayoutBuilder = new AlertDialog.Builder(this);
        gameOverLayoutBuilder.setView(gameOverLayout);
        gameOverLayoutBuilder.setPositiveButton(R.string.startGameAgainButtonText, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int id) {
                startGameAgainButtonPressed();
            }
        });

        gameOverLayoutBuilder.setNegativeButton(R.string.exitGameButtonText, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int id) {
                exitGameButtonPressed();
            }
        });

        gameOverLayoutAlertDialog = gameOverLayoutBuilder.create();
    }

    public void gameStartButtonPressed() {
        setGamePlaying(true);
        sendMessageTo("GS", ServerSession.toAllString);

        clientScoreArrayList.clear();

        gameStartLayoutDialog.dismiss();
    }

    public void startGameAgainButtonPressed() {
        gameOverLayoutAlertDialog.dismiss();

        gameStartLayoutDialog.show();
    }

    public void exitGameButtonPressed() {
        gameOverLayoutAlertDialog.dismiss();

        finish();
        // onPause() will send "IL" message to let clients know that server is leaving.
    }

    public void sendMessageTo(String message, String toNickName) {
        serverSession.sendMessageTo(message, toNickName);
    }


    class ConnectorListAdapter extends BaseAdapter {
        private Context mContext = null;
        private TextView connectorNameTextView = null;

        public ConnectorListAdapter(Context context) {
            mContext = context;
        }

        @Override
        public int getCount() {
            if (serverSession != null) {
                return serverSession.numberOfClients();
            } else {
                return 0;
            }
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View view, ViewGroup viewGroup) {
            View row = view;

            if (row == null) {
                row = LayoutInflater.from(mContext).inflate(R.layout.adapter_server_name_list, null);
            }

            String nicknameToShow = serverSession.getClientInfoListWith(position).getNickname();

            connectorNameTextView = (TextView)row.findViewById(R.id.serverNameTextView);
            connectorNameTextView.setText(nicknameToShow.substring(0, nicknameToShow.length() - 7));

            return row;
        }
    }

    class ScoreListAdapter extends BaseAdapter {
        private Context mContext = null;
        private TextView gradeTextView = null;
        private TextView nickNameTextView = null;
        private TextView scoreTextView = null;


        public ScoreListAdapter(Context context) {
            mContext = context;
        }

        @Override
        public int getCount() {
            return clientScoreArrayList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View view, ViewGroup viewGroup) {
            View row = view;

            if (row == null) {
                row = LayoutInflater.from(mContext).inflate(R.layout.adapter_score_list, null);
            }

            gradeTextView = (TextView)row.findViewById(R.id.gradeTextView);
            nickNameTextView = (TextView)row.findViewById(R.id.nickNameTextView);
            scoreTextView = (TextView)row.findViewById(R.id.scoreTextView);

            gradeTextView.setText((position + 1) + "");
            nickNameTextView.setText(clientScoreArrayList.get(position).getNickname());
            scoreTextView.setText(clientScoreArrayList.get(position).getScore() + "");

            return row;
        }
    }
}